package edu.hawaii.myisern.action;

import java.io.IOException;
import java.util.List;

import javax.xml.bind.JAXBException;

import edu.hawaii.myisern.collaborations.jaxb.Collaboration;
import edu.hawaii.myisern.model.Id;
import edu.hawaii.myisern.model.IsernManager;
import edu.hawaii.myisern.organizations.jaxb.Organization;
import edu.hawaii.myisern.researchers.jaxb.Researcher;
import net.sourceforge.stripes.action.DontValidate;
import net.sourceforge.stripes.action.ForwardResolution;
import net.sourceforge.stripes.action.RedirectResolution;
import net.sourceforge.stripes.action.Resolution;
import net.sourceforge.stripes.util.Log;
import net.sourceforge.stripes.validation.Validate;
import net.sourceforge.stripes.validation.ValidateNestedProperties;

/**
 * Handles request from create or update a Researcher.
 * 
 * @author Kevin English
 */
public class ResearcherFormActionBean extends IsernActionBean {
  /** A private copy of the log **/
  private static Log log = Log.getInstance(ResearcherFormActionBean.class);
  /** An error string, always displayed, but invisible if empty. */
  private String errorMessage = "";
  /** Singleton for use by action bean only. */
  //  private static IsernManager isern = new IsernManager();
  @ValidateNestedProperties( { @Validate(field = "name", required = true) })
  private Researcher researcher;
  private String newOrganization;
  private String id;
  /**
   * Get the researcher. 
   * @return A researcher
   */

  public Researcher getResearcher() {
    return this.researcher;
  }

  /**
   * Set the researcher object.
   * @param researcher A valid researcher object.
   */
  public void setResearcher(Researcher researcher) {
    this.researcher = researcher;
  }

  /**
   * Set the Id string used to identify a record.
   * @param id The id, usually the name.
   */
  public void setId(String id) {
    this.id = id;
  }

  /**
   * Get the Id string used to identify a record.
   * @return The Id string.
   */
  public String getId() {
    return this.id;
  }

  /**
   * Set the new organization string.
   * @param newOrg The new organization string.
   */
  public void setNewOrganization(String newOrg) {
    this.newOrganization = newOrg;
  }

  /**
   * Get the new organization string.
   * @return The new organization string.
   */
  public String getNewOrganization() {
    return this.newOrganization;
  }
  /**
   * Returns the error message.
   * @return The error message. 
   */
  public String getErrorMessage() {
    return this.errorMessage;
  }

  /**
   * Get collaborations by this researcher
   * 
   * @return a list of collaborations involving the organization to which the researcher belongs.
   */
  public  List<Collaboration> getCollaborationsByResearcher() {
    IsernManager im = new IsernManager();
    return im.getCollaborationsByResearcher(new Id(this.id));
  }
  
  /**
   * For new researcher, forward the user onto the jsp form.
   * @return The next jsp page.
   */
  /*
  @DefaultHandler
  public Resolution newResearcher() {
    return new ForwardResolution("/researcher_form.jsp");
  }
   */
  /**
   * Loads a researcher on to the form ready for editing.
   * @return The next jsp page.
   */
  @DontValidate
  public Resolution preEdit() {
    IsernManager im = new IsernManager();
    this.researcher = im.getResearcher(new Id(this.id));
    return new ForwardResolution("/researcher_form.jsp");
  }

  /**
   * Loads a researcher on to the form ready for view.
   * @return The next jsp page.
   */
  @DontValidate
  public Resolution view() {
    IsernManager im = new IsernManager();
    this.researcher = im.getResearcher(new Id(this.id));
    if (this.researcher == null) {
      this.errorMessage = "Researcher [" + this.id + "] not found.\n" +
          "Add it here or go back to check the source you click from.";
      this.id = null;
      return new ForwardResolution("/researcher_form.jsp");
    }
    return new ForwardResolution("/researcher_view.jsp");
  }
  
  /**
   * Remove the researcher.
   * @return The next jsp page.
   */
  @DontValidate
  public Resolution remove() {
    IsernManager im = new IsernManager();
    try {
      im.remove(new Id(this.id));
      try {
        im.save();
      }
      catch (IOException e) {
        this.errorMessage = "Error: cannot save(),IO Exception";
        e.printStackTrace();
      }
      catch (JAXBException e) {
        this.errorMessage = "Error: cannot save(),JAXB Exception";
        e.printStackTrace();
      }
    }
    catch (IOException e) {
      this.errorMessage = "Error: cannot remove(),IO Exception";
      e.printStackTrace();
    }
    return new ForwardResolution("/researchers.jsp");
  }
  
  /**
   * Creates (or updates) the researcher.
   * @return The next jsp page.
   */
  public Resolution save() {
    IsernManager im = new IsernManager();
    log.debug("new organization = " + this.newOrganization);
    log.debug("user_home " + System.getProperty("user.home") );
    if (this.newOrganization != null ) {
      Organization organization = new Organization();
      organization.setName(this.newOrganization);
      this.researcher.setOrganization(organization.getName());
      im.createOrganization(organization);
    }
    if (isUpdate(im)) {
      log.debug("Researcher save is update");
      im.updateResearcher(new Id(this.id), this.researcher);
     
    }
    else {
      log.debug("Researcher save is create");
      im.createResearcher(this.researcher);
    }
    try {
      im.save();
    }
    catch (IOException e) {
      this.errorMessage = "Error: cannot save(),IO Exception";
      e.printStackTrace();
    }
    catch (JAXBException e) {
      this.errorMessage = "Error: cannot save(),JAXB Exception";
      e.printStackTrace();
    }
    
    
    return new RedirectResolution("/researchers.jsp");
  }

  /**
   * Tells program if the record is new or update.
   * @param im An IsernManager object. 
   * @return True if the id exist and it is an update.
   */
  private boolean isUpdate(IsernManager im) {
    return (im.getResearcher(new Id(this.id)) != null);
  }

}